/**
 * @class   wosh::gui::WoshObject
 * @brief   Represent a generic remote object, used for message identification
 *          by other GUI components
 *          
 *
 ****************************************************************************
 * @version $Id: WoshObject.h 2488 2010-05-21 01:48:27Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Gui_WoshObject_H__
 #define __WOSH_Gui_WoshObject_H__

 #include <core/URI.h>
 #include <core/Utilities.h>

 #include <string>
 
 #include <QStringList>


namespace wosh {
 namespace gui {


class WoshObject  {

	public:

		WoshObject() {
			this->parent = NULL;
			this->updated = 0;
		 }

		WoshObject( const WoshObject& m ) {
			this->parent = NULL;
			*this = m;
		 }

		virtual ~WoshObject() { }


		WoshObject* clone() const								{ return new WoshObject(*this); }

/** @name Setters
 * @{
 ******************************************************************************/
	public:

		virtual void setRemoteName( const std::string& value )	{ this->rObjName = value; remoteObject_updated(); }
		virtual void setRemoteType( const std::string& value )	{ this->rObjType = value; remoteObject_updated(); }
		virtual void setRemoteURI( const URI& value )			{ this->rObjURI = value; remoteObject_updated(); }

		virtual void setParent( WoshObject* new_parent, bool fix_refs )
		{
			if ( fix_refs && this->parent != NULL && this->parent != new_parent ) {
				// changed parent!
				this->parent->getChildren().pop(this);
			 }
			this->parent = new_parent;
			if ( fix_refs && new_parent != NULL ) {
				if ( !new_parent->getChildren().exists(this) )
					new_parent->getChildren().push_back(this);
			 }

			remoteObject_updated();
		}

		virtual void setUpdated( long epoch = -1 ) {
			if ( epoch == -1 )
				this->updated = Utilities::std_time();
			else 
				this->updated = epoch;
		 }

//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:

		virtual const std::string& getRemoteName() const	{ return this->rObjName; }
		virtual std::string& getRemoteName()				{ return this->rObjName; }

		virtual const std::string& getRemoteType() const	{ return this->rObjType; }
		virtual std::string& getRemoteType()				{ return this->rObjType; }

		virtual const URI& getRemoteURI() const				{ return this->rObjURI; }
		virtual URI& getRemoteURI()							{ return this->rObjURI; }

		virtual const WoshObject* getParent() const			{ return this->parent; }
		virtual WoshObject* getParent()						{ return this->parent; }

		const QStringList& getInterfaces() const 			{ return this->interfaces; }
		QStringList& getInterfaces()						{ return this->interfaces; }
		
		virtual long getUpdated() const						{ return this->updated; }

//@}
/** @name Children access
 * @{
 ******************************************************************************/
	public:

		virtual int getChildrenCount() const					{ return this->children.size(); }

		virtual const ListT<WoshObject*>& getChildren() const	{ return this->children; }
		virtual ListT<WoshObject*>& getChildren()				{ return this->children; }

//@}
	public:
		WoshObject& operator=(const WoshObject& m) {
			this->interfaces = m.interfaces;
			this->updated = m.updated;
			this->rObjName = m.rObjName;
			this->rObjType = m.rObjType;
			this->rObjURI = m.rObjURI;
			this->parent = m.parent;
			return *this;
		 }




/** @name Internal methods and events
 * @{
 ******************************************************************************/
	protected:
		virtual inline void remoteObject_updated() { }

//@}
/** @name Internal fields
 * @{
 ******************************************************************************/
	protected:

		long updated;

		std::string rObjName;	///< name of the remote object (usually same as URI::getName())
		std::string rObjType;	///< type of the remote object, the C++ classname
		URI rObjURI;			///< URI of the remote object, this is the most important field

		ListT<WoshObject*> children;	///< optional list of children for hierarchical objects.
									///@note objects won't be freed or accessed by this class.
		WoshObject* parent;			///< optional parent reference for hierarchical objects. 
									///@note object won't be freed or accessed by this class.


		QStringList interfaces;


}; // class def

 }; // namespace gui
}; // namespace wosh


#endif //__WOSH_Gui_WoshObject_H__
